import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not, In, Like } from 'typeorm';
import { Injectable } from '@nestjs/common';
import { ResultData } from 'src/common/utils/result';
import { CreateClockDto, UpdateClockDto, QueryClockDto } from './dto/clock.dto';
import { ClockEntity } from './entities/clock.entity';
import { isEmpty } from 'src/common/utils';

@Injectable()
export class ClockService {
  constructor(
    @InjectRepository(ClockEntity)
    private readonly clockEntityRep: Repository<ClockEntity>,
  ) {}

  async create(createClockDto: CreateClockDto) {
    try {
      const res = await this.clockEntityRep.save(createClockDto);
      return ResultData.ok({ value: true });
    } catch (error) {
      return ResultData.ok({ value: false });
    }
  }

  async findAll(query: QueryClockDto) {
    const entity = this.clockEntityRep.createQueryBuilder('entity');
    entity.where({ delFlag: '0' });
    if (!isEmpty(query.id)) {
      entity.andWhere('entity.id = :id', { id: query.id });
    }
    if (!isEmpty(query.userId)) {
      entity.andWhere('entity.userId = :userId', { userId: query.userId });
    }
    if (!isEmpty(query.hour)) {
      entity.andWhere('entity.hour = :hour', { hour: query.hour });
    }
    if (!isEmpty(query.minute)) {
      entity.andWhere('entity.minute = :minute', { minute: query.minute });
    }
    if (!isEmpty(query.repeatDays)) {
      entity.andWhere('entity.repeatDays = :repeatDays', { repeatDays: query.repeatDays });
    }
    if (!isEmpty(query.isDaily)) {
      entity.andWhere('entity.isDaily = :isDaily', { isDaily: query.isDaily });
    }
    if (!isEmpty(query.templateId)) {
      entity.andWhere('entity.templateId = :templateId', { templateId: query.templateId });
    }
    if (!isEmpty(query.status)) {
      entity.andWhere('entity.status = :status', { status: query.status });
    }
    if (!isEmpty(query.delFlag)) {
      entity.andWhere('entity.delFlag = :delFlag', { delFlag: query.delFlag });
    }
    if (!isEmpty(query.createTime)) {
      entity.andWhere('entity.createTime BETWEEN :start AND :end', { start: query.createTime[0], end: query.createTime[1] });
    }
    if (!isEmpty(query.updateTime)) {
      entity.andWhere('entity.updateTime BETWEEN :start AND :end', { start: query.updateTime[0], end: query.updateTime[1] });
    }
    entity.select(['entity.id', 'entity.userId', 'entity.hour', 'entity.minute', 'entity.repeatDays', 'entity.isDaily', 'entity.templateId', 'entity.status']);

    if (query.orderByColumn && query.isAsc) {
      const key = query.isAsc === 'ascending' ? 'ASC' : 'DESC';
      entity.orderBy(`entity.${query.orderByColumn}`, key);
    }

    if (query.pageNum && query.pageSize) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }

    const [list, total] = await entity.getManyAndCount();

    return ResultData.ok({
      list,
      total,
    });
  }

  async findAllList(query: QueryClockDto) {
    const entity = this.clockEntityRep.createQueryBuilder('entity');
    entity.where({ delFlag: '0' });
    if (!isEmpty(query.id)) {
      entity.andWhere('entity.id = :id', { id: query.id });
    }
    if (!isEmpty(query.userId)) {
      entity.andWhere('entity.userId = :userId', { userId: query.userId });
    }
    if (!isEmpty(query.hour)) {
      entity.andWhere('entity.hour = :hour', { hour: query.hour });
    }
    if (!isEmpty(query.minute)) {
      entity.andWhere('entity.minute = :minute', { minute: query.minute });
    }
    if (!isEmpty(query.repeatDays)) {
      entity.andWhere('entity.repeatDays = :repeatDays', { repeatDays: query.repeatDays });
    }
    if (!isEmpty(query.isDaily)) {
      entity.andWhere('entity.isDaily = :isDaily', { isDaily: query.isDaily });
    }
    if (!isEmpty(query.templateId)) {
      entity.andWhere('entity.templateId = :templateId', { templateId: query.templateId });
    }
    if (!isEmpty(query.status)) {
      entity.andWhere('entity.status = :status', { status: query.status });
    }
    if (!isEmpty(query.delFlag)) {
      entity.andWhere('entity.delFlag = :delFlag', { delFlag: query.delFlag });
    }
    if (!isEmpty(query.createTime)) {
      entity.andWhere('entity.createTime BETWEEN :start AND :end', { start: query.createTime[0], end: query.createTime[1] });
    }
    if (!isEmpty(query.updateTime)) {
      entity.andWhere('entity.updateTime BETWEEN :start AND :end', { start: query.updateTime[0], end: query.updateTime[1] });
    }
    entity.select(['entity.id', 'entity.userId', 'entity.hour', 'entity.minute', 'entity.repeatDays', 'entity.isDaily', 'entity.templateId', 'entity.status']);

    if (query.orderByColumn && query.isAsc) {
      const key = query.isAsc === 'ascending' ? 'ASC' : 'DESC';
      entity.orderBy(`entity.${query.orderByColumn}`, key);
    }

    if (query.pageNum && query.pageSize) {
      entity.skip(query.pageSize * (query.pageNum - 1)).take(query.pageSize);
    }

    const [list, total] = await entity.getManyAndCount();

    return list;
  }

  async findOne(id: number) {
    const res = await this.clockEntityRep.findOne({
      where: {
        delFlag: '0',
        id: id,
      },
    });
    return ResultData.ok(res);
  }

  async update(updateClockDto: UpdateClockDto) {
    const res = await this.clockEntityRep.update({ id: updateClockDto.id }, updateClockDto);
    return ResultData.ok({ value: res.affected >= 1 });
  }

  async remove(id: number) {
    const res = await this.clockEntityRep.update(
      { id: id },
      {
        delFlag: '1',
      },
    );
    return ResultData.ok({ value: res.affected >= 1 });
  }

  async deleteByUserId(id: number) {
    const res = await this.clockEntityRep.update(
      { userId: id },
      {
        delFlag: '1',
      },
    );
    return res.affected >= 1;
  }
}
